let _Vue = null
export default class VueRouter {
  static install (vue) {
    // 1 判断当前插件是否被安装
    if (VueRouter.install.installed) return
    VueRouter.install.installed = true
    // 2 把Vue的构造函数记录在全局
    _Vue = vue
    // 3 把创建Vue的实例传入的router对象注入到Vue实例
    // _Vue.prototype.$router = this.$options.router
    _Vue.mixin({
      beforeCreate () {
        if (this.$options.router) {
          _Vue.prototype.$router = this.$options.router
        }
      }
    })
  }

  constructor (options) {
    this.mode = options.mode || "hash" // 默认为 hash 模式
    this.routes = options.routes
    this.routeMap = {}
    // observable 把current属性设为响应式变量 并赋给 Router 对象的 data 属性
    this.data = _Vue.observable({
      current: '/'
    })
    this.init()
  }
  init () {
    this.initRouteMap()
    this.initComponent(_Vue)
    this.initEvent()
  }
  initRouteMap () {
    //遍历所有路由信息，把组件和路由的映射记录到 routeMap 对象中
    this.routes.forEach( route => {
      this.routeMap[route.path] = route.component
    })
  }
  initComponent(Vue){
    //创建 router-link 和 router-view 组件
    // router-link 接受一个 to 参数
    const self = this
    Vue.component('router-link', {
      props:{
        to: String
      },
      render(h){
        // 创建一个 a 标签，并设置内容为插槽 $slots.default 的值
        return h("a", {
          attrs:{
            href: self.mode === "history" ? "" : "#" + this.to
          },
          on:{
            click:self.mode === "history" ? this.clickhander : this.hashClickhander
          }
        }, [this.$slots.default])
      },
      methods:{
        clickhander (e) {
          e.preventDefault()
          history.pushState({}, '', this.to)
          this.$router.data.current = this.to
        },
        hashClickhander (e) {
          this.$router.data.current = this.to
        }
      }
      // template:"<a :href='to'><slot></slot><>"
    })

    Vue.component('router-view', {
      render (h) {
        // 获取并渲染routes 中匹配的对应组件
        let comp = self.routeMap[self.data.current]
        return h(comp)
      }
    })
  }
  initEvent(){
    //注册 popstate 或 hashchange 事件，当路由地址发生变化，重新记录当前的路径
    const eventType = this.mode === 'history' ? 'popstate' : 'hashchange'
    const handle = this.mode === 'history' ? this.getLocation : this.getHash
    window.addEventListener(eventType, handle.bind(this))
  }
  getLocation(){
    this.data.current = window.location.pathname
  }
  getHash(){
    // 获取 hash 路径
    let href = window.location.href
    const index = href.indexOf('#')
    if (index < 0) return '/'
    // 取出 '#' 号后面的路由名称
    this.data.current = href.slice(index + 1)
  }
}
